package com.ukefu.webim.web.handler.api.rest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.webim.service.cache.CacheHelper;
import com.ukefu.webim.service.repository.ExtentionRepository;
import com.ukefu.webim.service.repository.PbxHostOrgiRelaRepository;
import com.ukefu.webim.service.repository.PbxHostRepository;
import com.ukefu.webim.service.repository.StatusEventRepository;
import com.ukefu.webim.util.HttpClientUtil;
import com.ukefu.webim.util.RestResult;
import com.ukefu.webim.util.RestResultType;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.handler.api.request.SearchData;
import com.ukefu.webim.web.model.Extention;
import com.ukefu.webim.web.model.PbxHost;
import com.ukefu.webim.web.model.PbxHostOrgiRela;
import com.ukefu.webim.web.model.StatusEvent;
import com.ukefu.webim.web.model.SystemConfig;

import io.swagger.annotations.ApiOperation;

@Controller
@RequestMapping("/api/callcenter")
public class ApiCallcenterController extends Handler{
	
	@Autowired
	private StatusEventRepository statusEventRes ;
	
	@Value("${web.upload-path}")
    private String path;
	
	@Autowired
	private PbxHostRepository pbxHostRes;
	
	@Autowired
	private ExtentionRepository extentionRes;
	
	@Autowired
	private PbxHostOrgiRelaRepository pbxHostOrgiRelaRepository ;
	
	/**
	 * 按条件查询
	 * @param map
	 * @param request
	 * @param ani
	 * @param called
	 * @param begin
	 * @param end
	 * @param direction
	 * @return
	 */
	@RequestMapping(value = "/search")
    @Menu(type = "callcenter" , subtype = "callcenter" , access = true)
	@ApiOperation("返回联系人列表，支持分页，分页参数为 p=1&ps=50，默认分页尺寸为 20条每页")
    public ResponseEntity<RestResult> index(ModelMap map , HttpServletRequest request ,@Valid final String discaller , @Valid final String discalled 
    		, @Valid final String begin , @Valid final String end , @Valid final String direction, @Valid final String userid, @Valid final String organ
    		,@Valid final String ringdurbegin ,@Valid final String ringdurend ,@Valid final String incallbegin ,@Valid final String incallend
    		,@Valid final String record ,@Valid final String misscall ,@Valid final String calltype,@Valid final String recordbegin,@Valid final String recordend) {
		final String orgi = super.getOrgi(request);
		Page<StatusEvent> page = statusEventRes.findAll(new Specification<StatusEvent>(){
			@Override
			public Predicate toPredicate(Root<StatusEvent> root, CriteriaQuery<?> query,
					CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();  
				if(!StringUtils.isBlank(discaller)){
					list.add(cb.equal(root.get("discaller").as(String.class), discaller)) ;
				}
				list.add(cb.equal(root.get("orgi").as(String.class), orgi)) ;
				if(!StringUtils.isBlank(discalled)){
					list.add(cb.equal(root.get("discalled").as(String.class), discalled)) ;
				}
				if(!StringUtils.isBlank(direction)){
					list.add(cb.equal(root.get("direction").as(String.class), direction)) ;
				}
				if(!StringUtils.isBlank(userid)){
					list.add(cb.equal(root.get("userid").as(String.class), userid)) ;
				}
				if(!StringUtils.isBlank(organ)){
					list.add(cb.equal(root.get("organ").as(String.class), organ)) ;
				}
				try {
					if(!StringUtils.isBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
						list.add(cb.greaterThan(root.get("createtime").as(Date.class), UKTools.dateFormate.parse(begin))) ;
					}
					if(!StringUtils.isBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}")){
						list.add(cb.lessThan(root.get("createtime").as(Date.class), UKTools.dateFormate.parse(end))) ;
					}
				} catch (ParseException e) {
					e.printStackTrace();
				}
				
				//振铃时长
				if(!StringUtils.isBlank(ringdurbegin)){
					list.add(cb.greaterThan(root.get("ringduration").as(int.class), Integer.parseInt(ringdurbegin)*1000)) ;
				}
				if(!StringUtils.isBlank(ringdurend)){
					list.add(cb.lessThan(root.get("ringduration").as(int.class), Integer.parseInt(ringdurend)*1000)) ;
				}
				
				//通话时长
				if(!StringUtils.isBlank(incallbegin)){
					list.add(cb.greaterThan(root.get("duration").as(int.class), Integer.parseInt(incallbegin)*1000)) ;
				}
				if(!StringUtils.isBlank(incallend)){
					list.add(cb.lessThan(root.get("duration").as(int.class), Integer.parseInt(incallend)*1000)) ;
				}
				
				//录音时长
				if(!StringUtils.isBlank(recordbegin)){
					list.add(cb.greaterThan(root.get("recordtime").as(int.class), Integer.parseInt(recordbegin)*1000)) ;
				}
				if(!StringUtils.isBlank(recordend)){
					list.add(cb.lessThan(root.get("recordtime").as(int.class), Integer.parseInt(recordend)*1000)) ;
				}
				
				//是否录音
				if(!StringUtils.isBlank(record)){
					list.add(cb.equal(root.get("record").as(boolean.class), record)) ;
				}
				
				//是否漏话
				if(!StringUtils.isBlank(misscall)){
					list.add(cb.equal(root.get("misscall").as(boolean.class), misscall)) ;
				}
				
				//呼叫方向
				if(!StringUtils.isBlank(calltype)){
					list.add(cb.equal(root.get("calltype").as(String.class), calltype)) ;
				}
				
				
				Predicate[] p = new Predicate[list.size()];  
			    return cb.and(list.toArray(p));  
			}}, new PageRequest(super.getP(request), super.getPs(request) , Sort.Direction.DESC, "starttime")) ;
		return new ResponseEntity<>(new RestResult(RestResultType.OK, new SearchData<StatusEvent>(page)), HttpStatus.OK);
    }
	
	/**
	 * 按条件查询
	 * @param map
	 * @param request
	 * @param ani
	 * @param called
	 * @param begin
	 * @param end
	 * @param direction
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping(value = "/voice")
    @Menu(type = "callcenter" , subtype = "voice" , access = true)
    public void play(ModelMap map , HttpServletRequest request , HttpServletResponse response ,@Valid final String id ) throws IOException {
		StatusEvent statusEvent = statusEventRes.findByIdAndOrgi(id ,super.getOrgi(request)) ;
		if(statusEvent!=null && !StringUtils.isBlank(statusEvent.getHostid())){
			PbxHost pbxHost = pbxHostRes.findByIdAndOrgi(statusEvent.getHostid(), statusEvent.getOrgi()) ;		//根据 PbxHost配置的 方式获取 录音文件的读取方式
			if(pbxHost != null && !StringUtils.isBlank(pbxHost.getRecordpath()) && pbxHost.getRecordpath() != "" && StringUtils.isNotBlank(statusEvent.getRecordfile())){
				String fileName = statusEvent.getRecordfile() ;
				if(statusEvent.getRecordfile().lastIndexOf("/") >= 0) {
					fileName = statusEvent.getRecordfile().substring(statusEvent.getRecordfile().lastIndexOf("/"), statusEvent.getRecordfile().length()) ;
				}else {
					fileName = "/"+fileName ;
				}
				response.sendRedirect(pbxHost.getRecordpath()+fileName);
			}else{
				if(statusEvent.getRecordfile() != null) {
                    //在远程oss
				    if("1".equals(statusEvent.getOssstatus())){
                        SystemConfig systemConfig = (SystemConfig) CacheHelper.getSystemCacheBean().getCacheObject("systemConfig", UKDataContext.SYSTEM_ORGI) ;
                        if(systemConfig != null && StringUtils.isNotBlank(systemConfig.getAppid())) {
                            String appId = systemConfig.getAppid();
                            Map<String,Object> paramsMap = new HashMap<>();
                            paramsMap.put("appId",appId);
                            paramsMap.put("objectName",statusEvent.getRecordfilename());
                            String res = HttpClientUtil.doPost(systemConfig.getCloudservergetossobjecturl(),paramsMap);

                            if(StringUtils.isNotBlank(res)){
                                @SuppressWarnings("unchecked")
								Map<String,Object> resultMap = UKTools.toObject(res,HashMap.class);
                                if(resultMap != null){
                                    Boolean success = (Boolean)resultMap.get("success");
                                    String url = (String)resultMap.get("resultObj");
                                    if(success != null && success && StringUtils.isNotBlank(url)){
                                        response.sendRedirect(url);
                                    }
                                }
                            }
                        }
                    }else{
                        File voiceFile = new File(statusEvent.getRecordfile()) ;
                        if(voiceFile != null && voiceFile.exists() && pbxHost!=null){
                            response.setContentType("audio/wav");
                            response.setContentLength((int) voiceFile.length());
                            FileInputStream input = new FileInputStream(voiceFile) ;
                            try{
                                byte[] data = new byte[1024];
                                int len = 0;
                                while((len = input.read(data) )> 0){
                                    response.getOutputStream().write(data , 0 , len);
                                }
                            }finally{
                                input.close();
                            }
                        }else {
                            response.setContentType("text/html");
                            String record = statusEvent.getRecordfile() ;
                            response.getOutputStream().write(record.getBytes());
                        }
                    }
				}else {
					response.setContentType("text/html");
					response.getOutputStream().write(statusEvent.getHostid().getBytes());
				}
			}
		}
    }
	
	@RequestMapping(value = "/pxhost/index")
    @Menu(type = "callcenter" , subtype = "callcenter" , access = true)
	@ApiOperation("返回语音平台列表")
    public ResponseEntity<RestResult> indexPxhost(ModelMap map , HttpServletRequest request) {
		List<PbxHost> topicList = new ArrayList<>();
		SystemConfig systemConfig = UKTools.getSystemConfig();
		//多租户 要查租户和语音服务器的关联表
		if(systemConfig!=null&&systemConfig.isEnabletneant()) {

			List<String> pbxHostIds = new ArrayList<>();
			List<PbxHostOrgiRela> pbxHostOrgiRelaList = pbxHostOrgiRelaRepository.findByOrgi(super.getOrgi(request)) ;

			if(!pbxHostOrgiRelaList.isEmpty()) {
				for(PbxHostOrgiRela rel:pbxHostOrgiRelaList) {
					pbxHostIds.add(rel.getPbxhostid());
				}
			}
			if(pbxHostIds.size() > 0){
				topicList = pbxHostRes.findByIdIn(pbxHostIds);
			}
		}else{
			topicList = pbxHostRes.findByOrgi(super.getOrgi(request)) ;
		}
		return new ResponseEntity<>(new RestResult(RestResultType.OK, topicList), HttpStatus.OK);
    }
	@RequestMapping(value = "/extention/index")
	@Menu(type = "callcenter" , subtype = "callcenter" , access = true)
	@ApiOperation("返回指定语音平台下的分机列表")
	public ResponseEntity<RestResult> indexExtention(ModelMap map , HttpServletRequest request ,@Valid final String hostid) {
		List<Extention> topicList = extentionRes.findByHostidAndExtypeAndOrgi(hostid , UKDataContext.ExtentionType.LINE.toString(), super.getOrgi(request));
		return new ResponseEntity<>(new RestResult(RestResultType.OK, topicList), HttpStatus.OK);
	}
}